Projeto completo em Javascript

Tempo estimado de leitura: 5min


Este tutorial têm como objetivo:

  • Elucidar melhor como funciona a arquitetura Cliente-Servidor
  • Demonstrar como preparar o ambiente da sua máquina
  • Demonstrar como funciona a estrutura de um projeto Javascript
  • Conseguir fazer uma interação completa entre o front, back e banco

Se trata de uma aplicação de mundo real, baseada no Medium: https://demo.realworld.io/#/ Pode encontrar mais informações sobre esse projeto aqui.

ProjetoStackUrl do projeto
BackendNode.js, Express, MongoDBhttps://github.com/gothinkster/node-express-realworld-example-app
FrontendReact, Reduxhttps://github.com/gothinkster/react-redux-realworld-example-app

Instalação

Clonar repositórios

$ mkdir conduit
$ cd conduit
$ git clone https://github.com/gothinkster/node-express-realworld-example-app backend
$ git clone https://github.com/gothinkster/react-redux-realworld-example-app frontend

Instalar MongoDB

MongoDB é um SGBD (Sistema Gerenciador de Banco de Dados) orientado a Documentos, sendo categorizado como NoSql.

$ wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
$ echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list
$ sudo apt update
$ sudo apt-get install -y mongodb-org
$ sudo systemctl start mongod
$ sudo systemctl status mongod
$ sudo mkdir -p /data/db
$ sudo chown -R `id -u` /data/db
$ mongod

Istalar NPM e Yarn

São gerenciadores de pacotes Javascript, portanto, utilizados para instalar bibliotecas externas.

  • npm = gerenciador padrão
  • yarn = surgiu com algumas otimizações em relação ao npm, sendo normalmente mais rápido

hoje em dia há quem argumente que ambos estão em pé de igualdade

$ sudo apt install nodejs npm
$ npm install --global yarn

Entendendo estrutura dos projetos

Felizmente, é bem simples de se abstrair o funcionamento de qualquer projeto JS: caso o README.md não providencie todas as informações necessárias, basta começar a ler pelo package.json :D

A partir da pasta conduit:

$ tree -L 2
.
├── backend
│   ├── app.js
│   ├── config
│   ├── models
│   ├── package.json
│   ├── project-logo.png
│   ├── public
│   ├── README.md
│   ├── routes
│   ├── tests
│   └── yarn.lock
└── frontend
    ├── package.json
    ├── project-logo.png
    ├── public
    ├── README.md
    ├── src
    └── yarn.lock

9 directories, 9 files

Package.json

Antes de começarmos a ler de fato ambos os package.json, vamos ver a similaridade destes:

backend/package.json:

{
  "name": "conduit-node",
  "version": "1.0.0",
  "description": "conduit on node",
  "main": "app.js",
  "scripts": {
    "mongo:start": "docker run --name realworld-mongo -p 27017:27017 mongo & sleep 5",
    "start": "node ./app.js",
    "dev": "nodemon ./app.js",
    "test": "newman run ./tests/api-tests.postman.json -e ./tests/env-api-tests.postman.json",
    "stop": "lsof -ti :3000 | xargs kill",
    "mongo:stop": "docker stop realworld-mongo && docker rm realworld-mongo"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/gothinkster/productionready-node-api.git"
  },
  "license": "ISC",
  "dependencies": {
    "body-parser": "1.15.0",
    "cors": "2.7.1",
    "ejs": "2.4.1",
    "errorhandler": "1.4.3",
    "express": "4.13.4",
    "express-jwt": "3.3.0",
    "express-session": "1.13.0",
    "jsonwebtoken": "7.1.9",
    "method-override": "2.3.5",
    "methods": "1.1.2",
    "mongoose": "4.4.10",
    "mongoose-unique-validator": "1.0.2",
    "morgan": "1.7.0",
    "passport": "0.3.2",
    "passport-local": "1.0.0",
    "request": "2.69.0",
    "slug": "0.9.1",
    "underscore": "1.8.3"
  },
  "devDependencies": {
    "newman": "^3.8.2",
    "nodemon": "^1.11.0"
  }
}

frontend/package.json:

{
  "name": "react-redux-realworld-example-app",
  "version": "0.1.0",
  "private": true,
  "devDependencies": {
    "cross-env": "^5.1.4",
    "react-scripts": "1.1.1"
  },
  "dependencies": {
    "history": "^4.6.3",
    "marked": "^0.3.6",
    "prop-types": "^15.5.10",
    "react": "^16.3.0",
    "react-dom": "^16.3.0",
    "react-redux": "^5.0.7",
    "react-router": "^4.1.2",
    "react-router-dom": "^4.1.2",
    "react-router-redux": "^5.0.0-alpha.6",
    "redux": "^3.6.0",
    "redux-devtools-extension": "^2.13.2",
    "redux-logger": "^3.0.1",
    "superagent": "^3.8.2",
    "superagent-promise": "^1.1.0"
  },
  "scripts": {
    "start": "cross-env PORT=4100 react-scripts start",
    "build": "react-scripts build",
    "test": "cross-env PORT=4100 react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}

Bom, fora o trivial (como name, version, description etc), o que salta aos olhos são: dependencies e scripts.

  • Scripts: são definidos pelo próprio desenvolvedor, sendo que podem ser até mesmo comandos que não utilizam alguma biblioteca JS. Por exemplo, poderiamos adicionar a chave "list": "ls" dentro de "scripts", e rodar o comando com npm run list ou yarn run list, que teria como output a listagem do diretório do repositório atual.

Obs: na maioria das vezes não é necessário incluir run no uso do yarn (ex: yarn build em vez de yarn run build); neste caso há de se incluir o run pois list é um comando padrão do yarn utilizado para listar todos os pacotes instalados neste projeto (incluindo dependencias das dependencias etc)

  • Dependencies: como o próprio nome da a entender, são as dependencias utilizadas naquele projeto. É sempre interessante/importante que você tenha ao menos uma noção do que as libs incluídas fazem... Basta acessar https://www.npmjs.com/package/ e incluir no final da url o pacote que está "inspecionando"; por exemplo: https://www.npmjs.com/package/marked

Você pode encontrar mais informações sobre o package.json aqui.

Instalando dependencias dos projetos

Antes de executarmos cada um dos projetos, precisamos instalar as dependencias previamente citadas: Abra dois terminais distintos (ou dê "split" caso seu terminal tenha essa opção), que serão referenciados aqui no tutorial como T1 e T2.

Segue, então, o passo-a-passo a ser realizado em cada um dos terminais:

Ambos a partir da pasta conduit

Comandos no T1

Comandos no T2

$ cd frontend
$ cd backend
$ yarn
$ yarn
$ yarn start
$ yarn dev

Url: localhost:3000

Url: localhost:4100

yarn é o mesmo npm install yarn start é o mesmo que npm run start yarn dev é o mesmo que npm run dev

Caso apareça um erro de conexão ao subir o serviço do backend como o mostrado abaixo, provavelmente acontecera por conta do serviço mongod não ter sido inicializado; para tanto, basta executar:

$ sudo systemctl start mongod

* obs: pode executar o mesmo comando acima substituindo start por enable para inicializar o serviço junto com o sistema operacional.

Mongod error

mongod_error


Agora, com ambos os serviços funcionando, você pode interagir com seu site localmente :D

Por ora é isso :) Veja os próximos capítulos para compreender melhor o funcionamento do Backend & Frontend.